<template>
	<view class="content" style="background-color: #F4F4F4;height: 100vh;">
		<tn-nav-bar bgClass="bg-gradual-blue" isBack>
			<view>
				{{ bleName }}
			</view>
		</tn-nav-bar>
		<view :style="{paddingTop: vuex_custom_bar_height + 'px'}" class="bg-white">
			<tn-sticky enabled :customNavHeight='vuex_custom_bar_height' class="bg-white">
				<view class="bg-white tn-margin">
					<tn-subsection class="bg-white tn-margin-top-sm " :list="topList"
						@change='tabChange'></tn-subsection>
				</view>
			</tn-sticky>

			<view class="margin-sm">
				<template v-if="topKey==='SUM_COUNT'">
					<view>
						<view class="margin-tb-sm">
							读取时间： <tn-number-box v-model="readTimes"></tn-number-box> <text
								class="padding-left-sm">秒</text>
						</view>
						<view class="margin-sm">
							<tn-button :fontSize='32' fontBold :shadow="true" width="100%" height="100rpx"
								v-if="!isRunTask" backgroundColor="tn-main-gradient-indigo" margin="10px 0"
								@click="startRun">开始统计</tn-button>
							<tn-button :fontSize='32' fontBold :shadow="true" width="100%" height="100rpx" v-else
								backgroundColor="tn-gary" margin="10px 0" disabled>统计中</tn-button>

						</view>
						<view class="" :style="{width: cWidth+'px',height: cHeight+'px'}">
							<qiun-data-charts ref="chart" :ontouch="true" type="mix" :opts="opts" :chartData="chartData"
								:width="cWidth" :height="cHeight" canvas2d />
						</view>
						<view style="width: 100%;" class="margin-tb-sm">
							<view class="text-bold text-xl margin-tb-sm">日志内容：</view>
							<tn-input v-model="logStr" type="textarea" :maxLength='-1' border style="font-size: 12px;"
								:clearable='false'></tn-input>
						</view>
					</view>

				</template>
				<template v-else>
					<view class="margin-tb-sm" v-for="key in Object.keys(configData[topKey].params)" :key="key">
						<tn-list-cell hover radius @click="showKeyboard(configData[topKey].params[key])"
							v-if="!hideArrays.includes(key)">
							<view class="list-icon-text">
								<view class="list__left">
									<view class="list__left__text">{{configData[topKey].params[key].text}}</view>
								</view>
								<view class="list__right">
									<text
										class="text-lg text-bold">{{configData[topKey].params[key].tValue?configData[topKey].params[key].tValue:0}}</text>
									<text class=" tn-flex-1 padding-left-sm">
										{{configData[topKey].params[key].unit}}</text>
								</view>
							</view>
						</tn-list-cell>
					</view>
				</template>
			</view>


			<view class="nav-index-button" style="right: 55px;bottom: 200px;" @tap.stop="sendFirstToBle(1)"
				v-if="topKey!=='SUM_COUNT'">
				<view class="nav-index-button__content">
					<view
						class="nav-index-button__content--icon tn-flex tn-flex-row-center tn-flex-col-center tn-shadow-blur tn-cool-bg-color-7">
						<view class="tn-icon-refresh"></view>
					</view>
				</view>
			</view>

			<view style="height: 10vh;"></view>

			<tn-modal :value="showKey" @click="setBleVal" @cancel="onDialogClose" custom :button="buttons"
				padding='30rpx'>
				<view class="custom-modal-content">
					<tn-form :labelWidth="140" style="width: 100%;">
						<tn-form-item :borderBottom="false" :label="activeItem.text" labelPosition="top">
							<tn-input v-model="inputValue" border type="number"></tn-input>
							<text slot="right" class="tn-text-bold">{{activeItem.unit}}</text>
						</tn-form-item>
					</tn-form>
				</view>
			</tn-modal>
		</view>
	</view>

</template>

<script>
	import BLE from "@/libs/bluetooth/BLE.js";
	import Protocol from "@/libs/protocol/jiabaida/protocol.js";
	import bleData from "@/libs/protocol/jiabaida/bleData.js";
	import utils from '@/common/utils/utils.js'

	let timer = null;
	let sendTimer = null;
	let _self = null

	const hideArrays = ['CreateDate', 'Cycle_Num']

	const factoryCMD = 'DD5A00025678FF3077'
	const outFactoryCMD = 'DD5A01022828FFAD77'

	export default {
		data() {
			return {
				cWidth: 375,
				cHeight: 250,
				isPage: false,
				isBreak: false,
				taskList: [],
				times: [],
				vList: [],
				aList: [],
				wList: [],
				bleName: '',
				readTimes: 30,
				logStr: '',
				resData: '',
				hideArrays: hideArrays,
				topKey: 'B_CONFIG',
				topList: _topList,
				inputValue: '',
				showKey: false,
				isRunTask: false,
				canSendCMD: true,
				isFirst: true,
				isWrite: false,
				readIndex: 0,
				activeItem: null,
				selectedMode: '1',
				PackInfo: bleData.packInfo,
				CONFIG: bleData.CONFIG,
				configData: bleData.CONFIG,
				buttons: [{
						text: '取消',
						backgroundColor: '#AAAAAA',
						fontColor: '#FFFFFF'
					},
					{
						text: '确定',
						backgroundColor: '#01BEFF',
						fontColor: '#FFFFFF'
					}
				],
				chartData: {},
				opts: {
					color: ["#FAC858", "#9A60B4", "#3CA272"],
					padding: [25, 5, 15, 5],
					update: true,
					rotateLock: false,
					rotate: false,
					enableScroll: true,
					legend: {},
					xAxis: {
						itemCount: 5,
						scrollAlign: 'right',
						rotateAngle: 10,
						rotateLabel: true,
						scrollShow: true,
						disableGrid: true,
					},
					yAxis: {
						disabled: false,
						disableGrid: false,
						splitNumber: 5,
						gridType: "dash",
						dashLength: 4,
						gridColor: "#CCCCCC",
						padding: 10,
						showTitle: true,
						data: [{
								position: "left",
								min: 0,
								max: 150,
								title: "电压(V)"
							},
							{
								position: "right",
								min: 0,
								max: 100,
								title: "电流(A)",
							},
							{
								position: "right",
								title: "功率(kw)",
							}
						]
					},
					extra: {
						mix: {
							column: {
								width: 20
							}
						}
					}
				}
			}
		},
		onLoad(options) {
			_self = this
			// 保持屏幕常亮
			uni.setKeepScreenOn({
				keepScreenOn: true
			});
			if (options.n) {
				this.bleName = options.n
			}
			this.getServerData()
		},
		onShow() {
			var that = this;
			_self = this
			if (timer != null) {
				clearInterval(timer)
				timer = null;
			}
			let readValue = {}
			that.SetValueChanged();

			CMDs = []
			for (let t in _self.CONFIG) {
				CMDs.push({
					name: t,
					cmd: 'DDA5FA03' + _self.CONFIG[t].CMD +
						Protocol.checkCRC16('FA03' + _self.CONFIG[t].CMD) +
						'77'
				})
				_self.configData = {
					..._self.configData,
					..._self.CONFIG[t].params
				}
			}
			that.readIndex = 0;
			this.sendFirstToBle();
		},
		methods: {
			startRun() {
				if (this.isRunTask) {
					console.log('运行中');
					return
				}
				this.logStr = ''
				this.canSendCMD = false
				this.isRunTask = true
				this.taskList = []
				this.times = []
				this.vList = []
				this.aList = []
				this.wList = []
				this.sendRunTaskCmd()
				setTimeout(() => {
					this.isRunTask = false;
					this.canSendCMD = true
					console.log('taskList:', this.taskList);
					this.getServerData()
				}, this.readTimes * 1000)
			},
			sendRunTaskCmd() {
				Protocol.writeStrToRead('DDA50300FFFD77', async () => {})
			},
			toHomePage() {
				uni.reLaunch({
					url: '/pages_ble/ble/tianyi'
				})
			},
			setBleVal(e) {
				if (e.index < 1) {
					this.showKey = false
					this.inputValue = ''
					return
				}
				let that = this
				this.$tn.message.toast('下发中')
				let address = that.activeItem.address
				let v = parseFloat(that.inputValue);
				if (!isNaN(v)) {
					this.canSendCMD = false;
					//先进入工厂模式
					Protocol.writeStrToRead('DD5A00025678FF3077', async () => {
						let address = that.activeItem.address
						let valHex = Protocol.encryption(address, v)
						setTimeout(() => {
							Protocol.writeToWrite('5A', 'FA', '05', (address * 1).toString(16)
								.toUpperCase().padStart(4, '0') + '01' + valHex,
								async () => {
									setTimeout(() => {
										that.$tn.message.toast('指令下发成功')
										that.showKey = false
										Protocol.writeStrToRead('DD5A01022828FFAD77',
											() => {
												setTimeout(() => {
													_self.sendFirstToBle();
												}, 500)
											});
									}, 1000)
								})
						}, 500)
					});
				} else {
					that.canSendCMD = true;
				}
			},
			onDialogClose() {
				this.showKey = false;
			},
			showKeyboard(item) {
				if (item.isDis) {
					return
				}
				this.canSendCMD = false
				this.activeItem = item;
				this.showKey = true
				this.inputValue = item.tValue
			},
			tabChange(e) {
				this.topKey = e.obj.key
			},
			radioChange(e) {
				this.selectedMode = e.detail.value;
				this.radioItems.forEach(item => {
					item.checked = (item.value === this.selectedMode);
				});
			},
			sendFirstToBle(flag) {
				let that = this
				that.isPage = true
				that.canSendCMD = true
				var state = getApp().globalData.bleObj.state;
				var deviceId = getApp().globalData.bleObj.deviceId;
				Protocol.writeStrToRead(CMDs[0].cmd, (res) => {
					if (flag) {
						that.$tn.message.toast('刷新数据成功')
					}
				});
			},
			//设置蓝牙请求数据
			SetValueChanged() {
				//处理数据
				BLE.bleCallBack.CharacteristicValueChange = (res) => {
					if (res === 'DD000000000077') {
						_self.canSendCMD = false
					}
					if (_self.canSendCMD) {
						var current = CMDs[_self.readIndex];
						let lastBit = res.substr(res.length - 2, res.length - 1)
						_self.resData += res
						if (lastBit === '77') {
							let CRC = _self.resData.substr(_self.resData.length - 6, 4)
							if (CRC === Protocol.checkCRC16(_self.resData.substr(4, _self.resData.length - 10))) {
								let packages = Protocol.solutionData(_self.resData)
								_self.SetTargetVal(_self.configData[current.name].params, packages.data)
								console.log('蓝牙返回数据：', _self.resData);
							}
							_self.resData = '';
							_self.readIndex++;
							if (_self.readIndex < CMDs.length) {
								Protocol.writeStrToRead(CMDs[_self.readIndex].cmd, function(res) {});
							} else {
								this.readIndex = 0
							}
						}
					} else {
						//定时任务 统计
						if (_self.isRunTask) {
							let lastBit = res.substr(res.length - 2, res.length - 1)
							_self.resData += res
							if (lastBit === '77') {
								let CRC = _self.resData.substr(_self.resData.length - 6, 4)
								if (CRC === Protocol.checkCRC16(_self.resData.substr(4, _self.resData.length - 10))) {
									let packages = Protocol.solutionData(_self.resData)
									let data = packages.data
									for (let itemKey in _self.PackInfo) {
										let item = _self.PackInfo[itemKey]
										if ('Temp' === item.name) {
											let num = _self.PackInfo['TempNum'].tValue
											let str = data.substr(0, num * 2 * 2)
											item.tValue = []
											for (var i = 0; i < num; i++) {
												let tStr = str.substr(i * 4, (i + 1) * 4)
												item.tValue.push(((parseInt('0x' + tStr) - 2731) * 0.1).toFixed(1))
											}
											data = data.substr(str.length, data.length)
										} else {
											item.value = '0x' + data.substr(0, item.len * 2)
											item.tValue = parseInt(item.value) * item.gain
											if ('CurCadc' === item.name) {
												var v = new Int16Array([parseInt(item.value, 16)])[0];
												item.tValue = (v * item.gain);
												//判断是否点击了 应急充电按钮
												if (_self.showTip && item.tValue > 0) {
													_self.setUVRValue("UP")
													_self.showTip = false;
												}
											}
											if (item.gain < 1) {
												item.tValue = item.tValue.toFixed(2)
											}
											//判断mos
											if (item.name === 'MosCtrl') {
												var v = parseInt(item.value).toString(2);
												item.tValue = v.split('').reverse();
											}
											data = data.substr(item.len * 2, data.length)
										}
									}
									const fen = utils.parseTime(new Date().getTime(), 'HH:mm:ss')
									const objItem = {
										time: fen,
										Voltage: _self.PackInfo['Voltage'].tValue,
										CurCadc: _self.PackInfo['CurCadc'].tValue,
									}
									objItem['Power'] = (objItem.Voltage * (objItem.CurCadc < 0 ? objItem.CurCadc * -1 :
										objItem.CurCadc)).toFixed(2)
									_self.logStr =
										`${objItem.time} 电压：${objItem.Voltage}V 电流：${objItem.CurCadc}A 功率：${objItem.Power}W \r\n` +
										_self.logStr;
									_self.taskList.push(objItem)
									_self.times.push(fen)
									_self.vList.push(objItem.Voltage)
									_self.aList.push(objItem.CurCadc)
									_self.wList.push((objItem.Power / 1000).toFixed(2))
									setTimeout(() => {
										_self.sendRunTaskCmd();
										_self.smoothUpdate(_self.times, _self.wList, _self.vList, _self.aList)
										// _self.getServerData();
									}, 800)
									_self.resData = '';
								}
							}
						}
					}
				}
			},
			SetTargetVal(targetObj, valStr) {
				valStr = valStr.substr(6, valStr.length - 1)
				let targetKeys = Object.keys(targetObj)
				for (var i = 0; i < targetKeys.length; i++) {
					let key = targetKeys[i]
					let target = targetObj[key]
					target.value = valStr.substr(i * 2 * target.len, 2 * target.len);
					if (target.name === 'CreateDate') {
						const tValue = parseDateFromHex('0x' + target.value);
						target.tValue = tValue;
						targetObj[key] = target
					} else {
						let num = Protocol.algorithm(target.address, target.value)
						const n = parseFloat(num);
						const tValue = isNaN(n) ? num : n % 1 === 0 ? n : parseFloat(n.toFixed(1));
						if (key === 'DOC') {
							var v = parseInt("0x" + target.value);
							target.tValue = parseFloat(((65536 - v) * 10).toFixed(1));
						} else {
							target.tValue = tValue;
						}
						targetObj[key] = target
					}
				}
			},
			smoothUpdate(times, wList, vList, aList) {
				let res = {
					animation: false,
					categories: times,
					series: [{
							name: "电压",
							type: "line",
							style: "curve",
							index: 0,
							data: vList,

						},
						{
							name: "电流",
							type: "line",
							index: 1,
							data: aList,
						}, {
							name: "功率",
							index: 2,
							type: "line",
							data: wList,
						},
					]
				};
				this.$refs.chart.updateData(res)
			},
			getServerData() {
				let res = {
					animation: false,
					categories: this.times,
					series: [{
							name: "电压",
							type: "line",
							style: "curve",
							index: 0,
							data: this.vList,
						},
						{
							name: "电流",
							type: "line",
							index: 1,
							data: this.aList,
						}, {
							name: "功率",
							index: 2,
							type: "line",
							data: this.wList,
						}
					]
				};
				this.chartData = JSON.parse(JSON.stringify(res));
			},
		}
	}

	function convertToHex(input, n) {
		// 步骤 1: 将输入字符串转为整数
		const number = parseInt(input, 10);
		// 步骤 2: 转为十六进制字符串，并转为大写
		let hex = number.toString(16).toUpperCase();
		// 步骤 3: 补零到 4 位
		while (hex.length < (n ? n : 4)) {
			hex = '0' + hex;
		}
		return hex;
	}

	function fullBuffer(originalBuffer) {
		if (originalBuffer.byteLength >= 128) {
			return originalBuffer; // 如果已经满足长度，直接返回
		}
		let newBuffer = new ArrayBuffer(128);
		let view = new Uint8Array(newBuffer);
		view.set(new Uint8Array(originalBuffer)); // 复制旧数据
		// 剩余字节自动填充为 0x00
		return newBuffer; // 返回新的 ArrayBuffer
	}

	function arrayBufferToHex(buffer) {
		if (buffer instanceof Uint8Array) {
			return Array.from(buffer)
		}
		const arr = new Uint8Array(buffer);
		return Array.from(arr)
			.map(b => b.toString(16).padStart(2, '0'))
			.join('');
	}

	function parseDateFromHex(hexValue) {
		// 提取日期
		let date = hexValue & 0x1f; // 最低5位表示日期

		// 提取月份
		let month = (hexValue >> 5) & 0x0f; // 第6到第9位表示月份

		// 提取年份
		let year = ((hexValue >> 9) & 0x3f) + 2000; // 最高6位表示年份，加上2000得到实际年份

		return `${year}年${month}月${date}日`;
	}
	const _topList = [{
			name: '基础参数',
			key: 'B_CONFIG'
		},
		{
			name: '保护配置',
			key: 'C_CONFIG'
		},
		{
			name: '数据统计',
			key: 'SUM_COUNT'
		}
	]
	let CMDs = []
</script>

<style lang="scss" scoped>
	progress {
		margin: 20rpx 0;
	}

	textarea {
		width: 100%;
		height: 200rpx;
		margin-top: 20rpx;
	}

	.nav-index-button {
		position: fixed;
		animation: suspension 3s ease-in-out infinite;
		z-index: 999999;

		&__content {
			position: absolute;
			width: 100rpx;
			height: 100rpx;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);


			&--icon {
				width: 100rpx;
				height: 100rpx;
				font-size: 60rpx;
				border-radius: 50%;
				margin-bottom: 18rpx;
				position: relative;
				z-index: 1;
				transform: scale(0.85);
			}
		}
	}



	.list {
		&__left {
			display: flex;
			align-items: center;
			justify-content: flex-start;

			&__icon,
			&__image {
				margin-right: 18rpx;
			}
		}

		&__right {
			display: flex;
			align-items: center;
			justify-content: flex-end;
		}
	}

	.list-icon-text,
	.list-image-text {
		display: flex;
		align-items: center;
		justify-content: space-between;
	}

	.list-image-text {
		.list {
			&__left {
				&__image {
					width: 20rpx;
					height: 20rpx;
				}
			}
		}
	}

	.charts-box {
		width: 100%;
		min-height: auto;
	}
</style>